package edu.scut.course_management.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import edu.scut.course_management.dao.AnswerAttachmentMapper;
import edu.scut.course_management.dao.AnswerMapper;
import edu.scut.course_management.dao.AttachmentMapper;
import edu.scut.course_management.dao.HomeworkAttachmentMapper;
import edu.scut.course_management.dao.HomeworkMapper;
import edu.scut.course_management.dao.SectionHomeworkMapper;
import edu.scut.course_management.dto.GetListOfStudentsDTO;
import edu.scut.course_management.dto.RequestForHCOStudentDTO;
import edu.scut.course_management.dto.SADetailInfoDTO;
import edu.scut.course_management.dto.SHBriefInfoDTO;
import edu.scut.course_management.dto.SHBriefInfoPreDTO;
import edu.scut.course_management.dto.SectionPlusStudentIdDTO;
import edu.scut.course_management.dto.StatisticsDTO;
import edu.scut.course_management.dto.SubmitHomeworkDTO;
import edu.scut.course_management.exception.CustomException;
import edu.scut.course_management.po.Answer;
import edu.scut.course_management.po.AnswerAttachment;
import edu.scut.course_management.po.Attachment;
import edu.scut.course_management.po.Homework;
import edu.scut.course_management.po.HomeworkAttachment;
import edu.scut.course_management.po.Section;
import edu.scut.course_management.po.SectionHomework;
import edu.scut.course_management.result.ResultCode;

/**
 * 作业管理模块服务
 * 
 * @author huaming
 */
@Service
public class HomeworkManagementService {

    @Autowired
    private HomeworkMapper homeworkMapper;

    @Autowired
    private AttachmentMapper attachmentMapper;

    @Autowired
    private AnswerMapper answerMapper;

    @Autowired
    private HomeworkAttachmentMapper homeworkAttachmentMapper;

    @Autowired
    private AnswerAttachmentMapper answerAttachmentMapper;

    @Autowired
    private SectionHomeworkMapper sectionHomeworkMapper;

    // 调用courseInfoService的接口
    @Autowired
    private CourseInfoService courseInfoService;

    /**
     * 新增课程作业记录
     * 
     * @param homework
     * @throws CustomException
     */
    public void addHomework(Homework homework) throws CustomException {
        try {
            homeworkMapper.addHomework(homework);
        } catch (DataAccessException e) {
            e.printStackTrace();
            throw new CustomException(ResultCode.DATABASE_UPDATE_FAIL);
        }
    }

    /**
     * 新增学生回答内容
     * 
     * @param answer
     * @throws CustomException
     */
    public void addAnswers(List<Answer> answers) throws CustomException {
        try {
            answerMapper.addAnswer(answers);
        } catch (DataAccessException e) {
            e.printStackTrace();
            throw new CustomException(ResultCode.DATABASE_UPDATE_FAIL);
        }
    }

    /**
     * 增加多个附件
     * 
     * @param attachmentList
     * @throws CustomException
     */
    public void addAttachment(List<Attachment> attachmentList) throws CustomException {
        try {
            attachmentMapper.addAttachmentList(attachmentList);
        } catch (DataAccessException e) {
            e.printStackTrace();
            throw new CustomException(ResultCode.DATABASE_UPDATE_FAIL);
        }
    }

    /**
     * 增加多个作业附件关联
     * 
     * @param homeworkAttachmentList
     * @throws CustomException
     */
    public void addHomeworkAttachment(List<HomeworkAttachment> homeworkAttachmentList) throws CustomException {
        try {
            homeworkAttachmentMapper.addHomeworkAttachment(homeworkAttachmentList);
        } catch (DataAccessException e) {
            e.printStackTrace();
            throw new CustomException(ResultCode.DATABASE_UPDATE_FAIL);
        }
    }

    /**
     * 增加多个学生回复内容与附件的关联
     * 
     * @param answerAttachmentsList
     * @throws CustomException
     */
    public void addAnswerAttachment(List<AnswerAttachment> answerAttachmentsList) throws CustomException {
        try {
            answerAttachmentMapper.addAnswerAttachment(answerAttachmentsList);
        } catch (DataAccessException e) {
            e.printStackTrace();
            throw new CustomException(ResultCode.DATABASE_UPDATE_FAIL);
        }
    }

    /**
     * 新增课程与作业的关联
     * 
     * @param sectionHomework
     * @throws CustomException
     */
    public void addSectionHomework(SectionHomework sectionHomework) throws CustomException {
        try {
            sectionHomeworkMapper.addSectionHomework(sectionHomework);
        } catch (DataAccessException e) {
            e.printStackTrace();
            throw new CustomException(ResultCode.DATABASE_UPDATE_FAIL);
        }
    }

    /**
     * 这个函数负责发布作业中所有需要插入记录的调用，方便回滚
     * 
     * @param homework
     * @param sectionHomework
     * @param attachments
     * @throws CustomException
     */
    @Transactional
    public void addAllOfPublish(Homework homework, SectionHomework sectionHomework, List<Attachment> attachments,
            List<Section> sections) throws CustomException {
        try {
            // 先插入homework记录
            addHomework(homework);
            // 获取刚插入的对象的ID
            sectionHomework.setHomeworkId(homework.getHomeworkId());
            // 建立homework与section的联系
            addSectionHomework(sectionHomework);
            // 增加附件
            if (!(attachments == null || attachments.size() == 0)) {
                addAttachment(attachments);
                // 构建homework与attachment的关系
                List<HomeworkAttachment> homeworkAttachments = new ArrayList<HomeworkAttachment>();
                for (Attachment each : attachments) {
                    HomeworkAttachment temp = new HomeworkAttachment();
                    temp.setAttachmentId(each.getAttachmentId());
                    temp.setHomeworkId(homework.getHomeworkId());
                    homeworkAttachments.add(temp);
                }
                // 插入上述构建的关系
                addHomeworkAttachment(homeworkAttachments);
            }
            // 查出该门课的所有学生
            List<GetListOfStudentsDTO> students = courseInfoService.getStudentsList(sections);
            // 构建answer
            List<Answer> answers = new ArrayList<Answer>();
            for (GetListOfStudentsDTO each: students) {
                Answer temp = new Answer();
                temp.setHomeworkId(homework.getHomeworkId());
                temp.setIsCheck(false);
                temp.setStudentId(each.getStudentId());
                temp.setAnswerContent("");
                temp.setScore(0);
                answers.add(temp);
            }
            addAnswers(answers);
        } catch (CustomException e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new CustomException(ResultCode.DATABASE_UPDATE_FAIL);            
        }
    }

    /**
     * 通过homework_id去answer表中搜索所有记录
     * @param homeworkId
     * @return
     */
    public List<SHBriefInfoDTO> findAllSHBriefInfoByHomeworkId(Integer homeworkId) {
        List<SHBriefInfoPreDTO> temp = answerMapper.findAnswerByHomeworkId(homeworkId);
        // 统计学生成绩各阶段信息
        int a[] = new int[]{0,0,0,0,0,0,0,0,0,0};
        // 对数据进行封装
        List<SHBriefInfoDTO> shBriefInfoDTOs = new ArrayList<>();
        for (SHBriefInfoPreDTO each:temp) {
            SHBriefInfoDTO shBriefInfoDTO = new SHBriefInfoDTO();
            shBriefInfoDTO.setName(each.getName());
            shBriefInfoDTO.setStudentId(each.getStudentId());
            shBriefInfoDTO.setScore(null);
            List<Attachment> attachments = attachmentMapper.findAttachmentsByAnswerId(each.getAnswerId());
            // 如果没有上传作业也没有回答内容 就是 未提交
            // 如果老师没有批改 但学生有回答内容就
            if (each.getIsCheck()) {
                shBriefInfoDTO.setIsCheck("已批改");
                shBriefInfoDTO.setScore(each.getScore());
            } else if ((attachments == null || attachments.size() == 0) && each.getAnswerContent().length() ==0) {
                shBriefInfoDTO.setIsCheck("未提交");
            } else {
                shBriefInfoDTO.setIsCheck("未批改");
            }

            shBriefInfoDTOs.add(shBriefInfoDTO);
        }
        return shBriefInfoDTOs;
    }

    /**
     * 通过homeworkId和studentId去answer去确定一条记录
     * @param homeworkId
     * @param studentId
     * @return
     */
    public Answer findAnswerByHomeworkIdAndStudentId(Integer homeworkId, String studentId) {
        return answerMapper.findAnswerByHomeworkIdAndStudentId(homeworkId, studentId);
    }

    /**
     * 通过homeworkId去homework表中查找记录
     * @param homeworkId
     * @return
     */
    public Homework findHomeworkByHomeworkId(Integer homeworkId) {
        return homeworkMapper.findHomeworkByHomeworkId(homeworkId);
    }

    /**
     * 通过homeworkId去homework_attachment和attachment级联表中查attachment
     * @param homeworkId
     * @return
     */
    public List<Attachment> findAttachmentsByHomeworkId(Integer homeworkId) {
        return attachmentMapper.findAttachmentsByHomeworkId(homeworkId);
    }
 
    /**
     * 通过answerId去answer_attachmen和attachment级联表中查attachment
     */
    public List<Attachment> findAttachmentsByAnswerId(Integer answerId) {
        return attachmentMapper.findAttachmentsByAnswerId(answerId);
    }

    /**
     * 通过section去section_homework和homework级联表中查homework
     * @param section
     * @return
     */
    public List<Homework> findHomeworkBySection(Section section) {
        return homeworkMapper.findHomeworkBySection(section);
    }

    /**
     * 用于检验section字段时候全为非空
     * @param section
     * @return
     */
    public boolean sectionNotNull(Section section) {
        return !(section.getBuildingId()==null || section.getCourseId()==null || section.getPeriodId()==null
            || section.getRoomNumber()==null || section.getTerm()==null || section.getYear()==null );
    }

    /**
     * 用section和studentId去查homework和answer
     * @param sectionPlusStudentIdDTO
     * @return
     */
    public List<RequestForHCOStudentDTO> findSADetailInfosBySectionPStudentId(SectionPlusStudentIdDTO sectionPlusStudentIdDTO) {
        // 获取数据
        List<SADetailInfoDTO> saDetailInfoDTOs = homeworkMapper.findSADetailInfoDTOsBySectionPlusStudentId(sectionPlusStudentIdDTO);
        // 日期格式转换设置
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 初始化
        List<RequestForHCOStudentDTO> requestForHCOStudentDTOs = new ArrayList<>();
        for (SADetailInfoDTO each: saDetailInfoDTOs) {
            RequestForHCOStudentDTO temp = new RequestForHCOStudentDTO();
            temp.setDeadline(dateFormat.format(each.getDeadline()));
            temp.setPublishTime(dateFormat.format(each.getPublishTime()));
            temp.setHomeworkContent(each.getHomeworkContent());
            temp.setHomeworkId(each.getHomeworkId());
            temp.setHomeworkTitle(each.getHomeworkTitle());
            temp.setScore(null);
            // 一下是检验作业的状态
            List<Attachment> attachments = attachmentMapper.findAttachmentsByAnswerId(each.getAnswerId());
            if (each.getIsCheck()) {
                temp.setScore(each.getScore());
                temp.setIsCheck("已批改");
            } else if (attachments == null || attachments.size() == 0 && each.getAnswerContent().length() == 0) {
                temp.setIsCheck("未提交");
            } else {
                temp.setIsCheck("未批改");
            }

            requestForHCOStudentDTOs.add(temp);
        }
        return requestForHCOStudentDTOs;
    }

    /**
     * 先通过homeworkId和studentId去查answer记录并更新answercontent 插入attachment
     * 最后插入answer_attachment
     * 
     * @param submitHomeworkDTOanswer
     * @throws CustomException
     */
    @Transactional
    public void updateAllAboutSending(SubmitHomeworkDTO submitHomeworkDTO) throws CustomException {
        try {answerMapper.updataAnswerContentByhomeworkIdAndStudentId(submitHomeworkDTO.getHomeworkId(), 
            submitHomeworkDTO.getStudentId(), submitHomeworkDTO.getAnswerContent()); 
            List<Attachment> attachments = submitHomeworkDTO.getAnswerAttachments();
            if (attachments==null || attachments.size()==0) return;
            Integer answerId = answerMapper.findAnswerIdByHomeworkIdAndStudentId(submitHomeworkDTO.getHomeworkId(), submitHomeworkDTO.getStudentId());
            if (!(attachments == null || attachments.size()==0)) {
                attachmentMapper.addAttachmentList(attachments);
                answerAttachmentMapper.addAnswerAttachmentByAttachmentsAndAnswerId(attachments, answerId);
            }
        } catch(DataAccessException e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new CustomException(ResultCode.DATABASE_UPDATE_FAIL);
        }
    }

    /**
     * 通过homeworkId和studentId确定answer记录并更新score与teacher_reply
     * @param homeworkId
     * @param studentIdteacher_reply
     * @param score
     * @param teacherReply
     * @throws CustomException
     */
    public void updateCorrectingContent(Integer homeworkId, String studentId, Integer score)
            throws CustomException {
        try {
            answerMapper.updateTAndScoreByHomeworkIdAndStudentId(homeworkId, studentId, score);
        } catch(DataAccessException e) {
            e.printStackTrace();
            throw new CustomException(ResultCode.DATABASE_UPDATE_FAIL);
        }
    }

    public StatisticsDTO getStatistics(Integer homeworkId) {
        List<SHBriefInfoPreDTO> temp = answerMapper.findAnswerByHomeworkId(homeworkId);
        StatisticsDTO statisticsDTO = new StatisticsDTO();
        int a,b,c,d,uncounted;
        a = 0; b = 0; c = 0; d = 0; uncounted = 0;
        for (SHBriefInfoPreDTO each: temp) {
            if (!each.getIsCheck()) {
                uncounted++;
            } else if (each.getScore() < 60) {
                d++;
            } else if (each.getScore() < 79) {
                c++;
            } else if (each.getScore() < 89) {
                b++;
            } else {
                a++;
            }
            statisticsDTO.setA(a);
            statisticsDTO.setB(b);
            statisticsDTO.setC(c);
            statisticsDTO.setD(d);
            statisticsDTO.setUncounted(uncounted);
        }

        return statisticsDTO;
    }

}